﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Diagnostics;

namespace Susam
{
    class FileScannerFactory
    {
        public IEnumerable<IFileScanner> GetScannerList(FileTypeOptions options)
        {
            if (options.scanEpubs == true) yield return new EpubScanner();
            if (options.scanPDFs == true) yield return new PdfScanner();
        }
    }

    interface IFileScanner
    {
        void Scan(String path, ManualResetEvent doneEvent);
    }

    class EpubScanner : FileScanner
    {
        protected override void InternalScanner()
        {
            IFileParser parser = FileParserFactory.CreateParser("*.epub");
            var files = base.GetFileList("*.epub");
            UpdateDatabase(files, parser);
        }
    }

    class PdfScanner : FileScanner
    {
        protected override void InternalScanner()
        {
            IFileParser parser = FileParserFactory.CreateParser("*.pdf");
            var files = GetFileList("*.pdf");
            UpdateDatabase(files, parser);
        }
    }

    abstract class FileScanner: IFileScanner
    {
        private String _path;
        private ManualResetEvent _doneEvent;

        public void Scan(String path, ManualResetEvent doneEvent)
        {
            if (path == null || doneEvent == null)
            {
                // TODO: Handle this, log error
                Debug.WriteLine("FATAL: Invalid path!");
                return;
            }

            this._path = path;
            this._doneEvent = doneEvent;

            Thread scanner = new Thread(InternalScanner);
            scanner.Start();
        }

        protected void UpdateDatabase(IEnumerable<String> files, IFileParser parser)
        {
            var dbManager = DatabaseManager.Instance;

            foreach (String file in files)
            {
                Metadata meta = parser.Parse(file);
                dbManager.Update(meta);
            }
            this._doneEvent.Set();
        }

        protected abstract void InternalScanner();

        protected IEnumerable<String> GetFileList(String filter)
        {
            IEnumerable<String> files = null;
            try
            {
                files = Directory.EnumerateFiles(this._path, filter, SearchOption.AllDirectories);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
            return files;
        }

    }
}
